/**
 * 本程序使用RTMP_ReadPacket与RTMP_ClientPacket方式读取流数据，接收RTMP流媒体并存储视频h264和音频aac文件。
*/

#include "RtmpAudio.h"

//生成ADTS
int RtmpAudio::CreateADTS(AudioSpecificConfig ascAudioSpecificConfig, unsigned short nAudioFrameLength, char *pADTS)
{
	if (pADTS == NULL)
	return -1;

	unsigned char adts[7] = { 0 };
	int chanCfg = ascAudioSpecificConfig.nChannels;
	// fill in ADTS data
	adts[0] = (byte)0xFF;
	adts[1] = (byte)0xF9;
	adts[2] = (byte)(((ascAudioSpecificConfig.nAudioObjectType - 1) << 6) + (ascAudioSpecificConfig.nSampleFrequencyIndex << 2) + (chanCfg >> 2));
	adts[3] = (byte)(((chanCfg & 3) << 6) + (nAudioFrameLength >> 11));
	adts[4] = (byte)((nAudioFrameLength & 0x7FF) >> 3);
	adts[5] = (byte)(((nAudioFrameLength & 7) << 5) + 0x1F);
	adts[6] = (byte)0xFC;

	if (pADTS != NULL)
	{
		memcpy(pADTS, adts, sizeof(adts));
	}
	return 0;
}
int RtmpAudio::initRtmp(){
	rtmp = RTMP_Alloc();
	RTMP_Init(rtmp);
	//set connection timeout,default 30s
	rtmp->Link.timeout = 30;
	//if(!RTMP_SetupURL(rtmp,"rtmp://192.168.0.118:80/live/stream"))
	// HKS's live URL
	if(!RTMP_SetupURL(rtmp,"rtmp://live.hkstv.hk.lxdns.com/live/hks"))
	{
		RTMP_Log(RTMP_LOGERROR, "SetupURL Err\n");
		RTMP_Free(rtmp);

		return -1;
	}

	rtmp->Link.lFlags |= RTMP_LF_LIVE;

	//1hour
	RTMP_SetBufferMS(rtmp, 3600 * 1000);

	if (!RTMP_Connect(rtmp, NULL)){
		RTMP_Log(RTMP_LOGERROR, "Connect Err\n");
		RTMP_Free(rtmp);
		return -1;
	}

	if (!RTMP_ConnectStream(rtmp, 0)){
		RTMP_Log(RTMP_LOGERROR, "ConnectStream Err\n");
		RTMP_Close(rtmp);
		RTMP_Free(rtmp);
		return -1;
	}
	return 0;
}

void RtmpAudio::destoryRtmp(){

		if (fpAAC)
			fclose(fpAAC);

		if (rtmp){
			RTMP_Close(rtmp);
			RTMP_Free(rtmp);
			rtmp = NULL;
		}

}
//直播
int RtmpAudio::Run()
{
	double duration=-1;
	int nRead;
	int bufsize=1024*1024*10;
	int nCount = 0;
	RTMPPacket pc = { 0 };// ps = { 0 };
	bool bVideoFirst = true;
	bool bAudioFirst = true;
	unsigned int nFrameType = 0;
	unsigned char result = 0;
	char *data = NULL;
	//FLV文件头
	static const char flvHeader[] = { 'F', 'L', 'V', 0x01,
		0x00,				/* 0x04代表有音频, 0x01代表有视频 */
		0x00, 0x00, 0x00, 0x09,
		0x00, 0x00, 0x00, 0x00
	};
	AudioSpecificConfig ascAudioSpecificConfig = { 0 };
	int nResult = 0;
	bool bHasMediaPacket = false;
	bool bConnected = false;
	initRtmp();
	while (!bHasMediaPacket && (bConnected=RTMP_IsConnected(rtmp))&& RTMP_ReadPacket(rtmp, &pc))
	{
		if (RTMPPacket_IsReady(&pc))	//是否读取完毕。((a)->m_nBytesRead == (a)->m_nBodySize)
		{
			if (!pc.m_nBodySize)
				continue;

			bHasMediaPacket =RTMP_ClientPacket(rtmp, &pc);
			if(!bHasMediaPacket)
				continue;

			// RTMP_LogPrintf("begin-%5d\n",bHasMediaPacket);
			if (pc.m_packetType == RTMP_PACKET_TYPE_VIDEO)
			{

			}
			else if (pc.m_packetType == RTMP_PACKET_TYPE_AUDIO)
			{
				data = pc.m_body;
				if (bAudioFirst)
				{
					//ACC音频同步包(1bytes+3bytes AccAudioData) (4bytes 包含了AACDecoderSpecific和AudioSpecificConfig)
					AACDecoderSpecific adsAACDecoderSpecific = { 0 };
					adsAACDecoderSpecific.nAudioFortmatType = (data[0] & 0xf0) >> 4;	//音频编码类型（0：Liner PCM platform endian，1：PCM，2：mp3，4：Nellymoser 16-kHz mono,5:Nellymoser 8-kHz mono,6:Nellymoser,7:G.711 A-law logarithmic PCM,8:G.711 mu-law logarithmic PCM,9:reserved,10: AAC,14:MP3 8-Khz,15:Device-specific sound）
					adsAACDecoderSpecific.nAudioSampleType = (data[0] & 0x0c) >> 2;	//音频采样率(0:5.5kHz,1:11KHz,2:22 kHz,3:44 kHz)
					adsAACDecoderSpecific.nAudioSizeType = (data[0] & 0x02) >> 1;	//音频采样精度(0:8bits,1:16bits)
					adsAACDecoderSpecific.nAudioStereo = data[0] & 0x01;//是否立体声(0:sndMono,1:sndStereo)

					RTMP_LogPrintf("ACC音频同步包: 编码类型:%5d, 采样率: %5d,采样精度:%5d,是否立体声:%5d\n",adsAACDecoderSpecific.nAudioFortmatType
						,adsAACDecoderSpecific.nAudioSampleType,adsAACDecoderSpecific.nAudioSizeType,adsAACDecoderSpecific.nAudioStereo);

					if(adsAACDecoderSpecific.nAudioFortmatType == 10)
					{
						//The following values are defined:
						//0 = AAC sequence header
						//1 = AAC raw
						adsAACDecoderSpecific.nAccPacketType = data[1];
						unsigned short audioSpecificConfig = 0;
						audioSpecificConfig = (data[2] & 0xff) << 8;
						audioSpecificConfig += 0x00ff & data[3];
						ascAudioSpecificConfig.nAudioObjectType = (audioSpecificConfig & 0xF800) >> 11;
						ascAudioSpecificConfig.nSampleFrequencyIndex = (audioSpecificConfig & 0x0780) >> 7;
						ascAudioSpecificConfig.nChannels = (audioSpecificConfig & 0x78) >> 3;
						ascAudioSpecificConfig.nFrameLengthFlag = (audioSpecificConfig & 0x04) >> 2;
						ascAudioSpecificConfig.nDependOnCoreCoder = (audioSpecificConfig & 0x02) >> 1;
						ascAudioSpecificConfig.nExtensionFlag = audioSpecificConfig & 0x01;
					}
					else if(adsAACDecoderSpecific.nAudioFortmatType == 11)
					{
						//speex类型数据时，后面的4位数据不起作用，固定的是16KHZ，单声道，16bit/sample
						adsAACDecoderSpecific.nAudioStereo = 0;
						adsAACDecoderSpecific.nAudioSizeType = 1;
						adsAACDecoderSpecific.nAudioSampleType = 4;
					}
					bAudioFirst = false;
				}
				else
				{
					if(pc.m_nBodySize > 2)
					{
						if(data[1] == 1)
						{
							//raw data 获取 audio payload
							//写ADTS数据到文件
							char szADTSTemp[8] = { 0 };
//							RTMP_LogPrintf("bodysize：%5d\n",pc.m_nBodySize);
							CreateADTS(ascAudioSpecificConfig, pc.m_nBodySize - 2 + 7, szADTSTemp);
							fwrite(szADTSTemp, 7, 1, fpAAC);
							//写raw数据到文件
							fwrite(pc.m_body + 2, pc.m_nBodySize - 2, 1, fpAAC);

							pMemAudio->appendBuffer(szADTSTemp,7,false);
							pMemAudio->appendBuffer(pc.m_body + 2,pc.m_nBodySize - 2,true);
						}
					}
				}
			}
			RTMPPacket_Free(&pc);
			bHasMediaPacket = false;
		}
	}

	destoryRtmp();
	return 0;
}

void RtmpAudio::OnThreadTick(){
	Run();
}
